package org.crackjack.services;

import java.io.IOException;
import java.util.List;

import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.node.ObjectNode;
import org.crackjack.dao.ProfileDao;
import org.crackjack.model.Profile;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

@Controller
@RequestMapping(value = "/profile")
public class ProfileController extends GenericController {

    @Autowired
    private ProfileDao profileDao;

    @RequestMapping(value = "/registration", method = RequestMethod.GET)
    @ResponseBody
    public ResponseEntity<String> registration(@RequestParam(value = "login", required = true) String login,
            @RequestParam(value = "password", required = true) String password) {

        ObjectMapper mapper = new ObjectMapper();
        ObjectNode node = mapper.createObjectNode();

        if (profileDao.registration(login, password)) {
            node.put("status", "success");
        } else {
            node.put("status", "failure");
        }

        try {
            return getResponseInJsonType(mapper.writeValueAsString(node));
        } catch (JsonGenerationException e) {
            return getResponseInJsonType(generateExceptionJson(e));
        } catch (JsonMappingException e) {
            return getResponseInJsonType(generateExceptionJson(e));
        } catch (IOException e) {
            return getResponseInJsonType(generateExceptionJson(e));
        }
    }

    @RequestMapping(value = "/authorization", method = RequestMethod.GET)
    @ResponseBody
    public ResponseEntity<String> authorization(@RequestParam(value = "login", required = true) String login,
            @RequestParam(value = "password", required = true) String password) {

        ObjectMapper mapper = new ObjectMapper();
        ObjectNode node = mapper.createObjectNode();
        if (profileDao.authorization(login, password)) {

            node.put("status", "success");
        } else {
            node.put("status", "failure");
        }
        try {
            return getResponseInJsonType(mapper.writeValueAsString(node));
        } catch (JsonGenerationException e) {
            return getResponseInJsonType(generateExceptionJson(e));
        } catch (JsonMappingException e) {
            return getResponseInJsonType(generateExceptionJson(e));
        } catch (IOException e) {
            return getResponseInJsonType(generateExceptionJson(e));
        }
    }

    @RequestMapping(value = "/list", method = RequestMethod.GET)
    @ResponseBody
    public ResponseEntity<List<Profile>> getProfiles() {
        List<Profile> profiles = profileDao.getList();
        for (Profile p : profiles) {
            p.setAppointments(null);
        }
        return getResponseInJsonType(profiles);

    }

    @RequestMapping(value = "/delete/{id}", method = RequestMethod.DELETE)
    @Transactional(rollbackFor = Exception.class)
    @ResponseStatus(HttpStatus.OK)
    public void deleteProfile(@PathVariable("id") long id) {
        profileDao.delete(id);
    }

    @RequestMapping(value = "/update", method = RequestMethod.PUT)
    @Transactional(rollbackFor = Exception.class)
    @ResponseStatus(HttpStatus.OK)
    public void updateProfile(@RequestBody Profile profile) {
        profileDao.update(profile);
    }

    private String generateExceptionJson(Exception e) {
        return " {\"status\":\"failure\",\"error\":\"" + e.getMessage() + "\"}";
    }

}
